let flushing = false, waiting = false, pending = false
const queues = [], callbacks = []
export default function watcherQueue(watcher) {
    // watcher去重
    if (queues.includes(watcher)) return
    if (!flushing) {
        // 如果watcher队列当前没有被刷新 那么直接将watcher入队
        queues.push(watcher)
    } else {
        // 将watcher插入到有序队列中
        let index = queues.length - 1
        while (index >= 0 && queues[index].uid > watcher.uid) index--
        if (index < 0) {
            queues.unshift(watcher)
        } else {
            queues.splice(index + 1, 0, watcher)
        }
    }
    // 每次只进入一个刷新队列
    if (!waiting) {
        waiting = true
        // nextTick 就是我们所见到的 Vue.nextTick this.$nextTick
        nextTick(flushSchedulerQueue)
    }

    function nextTick(cb) {
        // 将用户的回调 以及 我们自己的用于更新watcher队列的回调都添加进回调函数队列
        callbacks.push(cb)
        // 如果当前的callbacks正在被刷新 那么等待下次执行 
        if (!pending) {
            // 这里其实就相当于源码中的timerFunc函数 只是简陋了些
            pending = true
            Promise.resolve().then(flushCallbacks)
        }
    }
    // 负责刷新callbacks
    function flushCallbacks() {
        pending = false
        while (callbacks.length) {
            const cb = callbacks.shift()
            cb() // 执行回调 其中肯定会执行一次flushSchedulerQueue
        }
    }
    // 负责刷新watcher 队列
    function flushSchedulerQueue() {
        flushing = true // 正在刷新
        queues.sort((a, b) => a.uid - b.uid)
        // 在更新过程中可能会有新的watcher入队
        while (queues.length) {
            const watcher = queues.shift()
            // 通知watcher去更新数据
            watcher.run()
        }
        // 刷新完了
        flushing = waiting = false
    }
}
